package components.map
{
	import capricornus.components.ComponentsManager;
	import capricornus.components.utils.FilterUtils;
	import capricornus.core.StageManager;
	import capricornus.events.StageEvent;
	
	import components.alert.Alert;
	import components.editbar.EditBarController;
	import components.map.componentdrag.ComponentDragManager;
	import components.map.grid.MapGridController;
	import components.map.info.MapInfoPopupController;
	import components.map.path.MapPathController;
	import components.map.utils.EditType;
	import components.map.utils.SceneItemType;
	import components.toolbar.ToolBarController;
	import components.utils.file.FileManager;
	
	import flash.display.Graphics;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.ui.Keyboard;
	import flash.utils.ByteArray;
	import flash.utils.getTimer;

	public class MapController
	{
		public static var instance:MapController;
		
		private var _view:MapView;
		private var _mapName:String;
		private var _gridController:MapGridController;
		private var _pathController:MapPathController;
		private var _dragManager:ComponentDragManager;
		
		private var _isDrag:Boolean = false;
		private var _isCreated:Boolean = false;
		private var _editType:int = EditType.ITEM;
		
		private var _txtTips:TextField;
		
		public function MapController()
		{
			init();
		}
		
		private function init():void
		{
			instance = this;
			
			_view = new MapView( ComponentsManager.instance.middleLayer );
			_view.show();
			
			_gridController = new MapGridController( _view.gridLayer );
			_pathController = new MapPathController( _view, _gridController );
			_dragManager = new ComponentDragManager( _view.dragLayer, _view );
			
			_txtTips = new TextField();
			_txtTips.textColor = 0xff0000;
			_txtTips.alpha = 0.8;
			_txtTips.filters = FilterUtils.getBlackGlowFilter();
			_txtTips.mouseEnabled = false;
			StageManager.stage.addChild( _txtTips );
			
			_view.addEventListener( MouseEvent.MOUSE_MOVE, onMouseMove, false, 0, true );
			StageManager.stage.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDown, true, int.MAX_VALUE, true );
			StageManager.stage.addEventListener( MouseEvent.CLICK, onClickStage, false, 0, true );
			
			StageManager.instance.addEventListener( StageEvent.RESIZE, onResize, false, 0, true );
		}
		
		private function onResize( e:StageEvent ):void
		{
			ComponentsManager.instance.middleLayer.scrollRect = new Rectangle( 0, 0, StageManager.stageWidth, StageManager.stageHeight );
			_txtTips.x = StageManager.stageWidth - _txtTips.width;
			_txtTips.y = StageManager.stageHeight - _txtTips.height;
		}
		
		private function setTips( str:String ):void
		{
			_txtTips.htmlText = str;
			_txtTips.width = _txtTips.textWidth + 4;
			_txtTips.height = _txtTips.textHeight + 4;
			_txtTips.x = StageManager.stageWidth - _txtTips.width;
			_txtTips.y = StageManager.stageHeight - _txtTips.height;
		}
		
		public function open():void
		{
			FileManager.instance.open();
		}
		
		public function news():void
		{
			if( _isCreated )
			{
				Alert.show( "尚未保存，是否保存？", callBackSave, callBackCancel );
			}
			else
			{
				infoPopupController.show();
			}
		}
		
		private function callBackSave():void
		{
			clear();
			infoPopupController.show();
		}
		
		private function callBackCancel():void
		{
			clear();
			infoPopupController.show();
		}
		
		public function save():void
		{
			
		}
		
		public function saveAs():void
		{
			FileManager.instance.saveAs( _mapName, getByteData(), _view.imageBG.source );
		}
		
		/**
		 * 
		 * @param w
		 * @param h
		 * @param gridWidth gridWidth=gridHeight*2
		 * @param gridHeight
		 * 
		 */		
		public function createNewMap( name:String, w:int, h:int, gridWidth:int, gridHeight:int ):void
		{
			_mapName = name;
			_isCreated = true;
			gridHeight = gridWidth / 2;
			_view.show();
			_view.scrollRect = new Rectangle( 0, 0, w, h );
			
			_view.back.width = w;
			_view.back.height = h;
			
			_view.gridMask.width = w;
			_view.gridMask.height = h;
			
			_view.backLayerMask.width = w;
			_view.backLayerMask.height = h;
			
			_view.setLocation( (StageManager.stageWidth - ToolBarController.instance.width - w)/2, (StageManager.stageHeight - h)/2 );
			_dragManager.isMapInit = true;
			_dragManager.setSize( w, h );
			
			_gridController.reset( w, h, gridWidth, gridHeight );
			_pathController.reset();
			_pathController.setBorderReadOnly();
			_pathController.resetPen();
			
			StageManager.stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true );
			StageManager.stage.addEventListener( KeyboardEvent.KEY_UP, onKeyUp, false, 0, true );
		}
		
		public function setMapData( byte:ByteArray, name:String, bgURL:String ):void
		{
			clear();
			byte.uncompress();
			createNewMap( name, byte.readShort(), byte.readShort(), byte.readShort(), byte.readShort() );
			var n:int = byte.readShort();
			var b:ByteArray = new ByteArray();
			byte.readBytes( b );
			_pathController.setPathData( b );
			_view.imageBG.source = bgURL;
		}
		
		public function setBGImage( url:String ):void
		{
			_view.imageBG.source = url;
		}
		
		private function getByteData():ByteArray
		{
			var byte:ByteArray = new ByteArray();
			byte.writeBytes( _gridController.getGridData() );
			byte.writeBytes( _pathController.getPathData() );
			byte.compress();
			
			return byte;
		}
		
		public function get isMapCreated():Boolean
		{
			return _isCreated;
		}
		
		public function set scale( value:Number ):void
		{
			_view.scaleX = _view.scaleY = value;
			_view.setLocation( (StageManager.stageWidth - ToolBarController.instance.width - _view.back.width * value)/2, (StageManager.stageHeight - _view.back.height * value)/2 );
		}
		
		public function setGridAlpha( gridAlpha:Number, lineAlpha:Number ):void
		{
			if( gridAlpha != -1 ) _view.backLayer.alpha = gridAlpha;
			if( lineAlpha != -1 ) _view.gridLayer.alpha = lineAlpha;
		}
		
		public function setGridVisible( value:Boolean ):void
		{
			_view.backLayer.visible = _view.gridLayer.visible = value;
		}
		
		public function setItemVisible( value:Boolean ):void
		{
			_view.itemLayer.visible = value;
		}
		
		public function set editType( value:int ):void
		{
			_editType = value;
			if( _editType==EditType.ITEM )
			{
				_pathController.enabled = false;
				_view.itemLayer.alpha = 1;
				_view.itemLayer.mouseChildren = true;
			}
			else
			{
				_dragManager.startDrag( SceneItemType.NONE );
				_pathController.enabled = true;
				_pathController.editType = _editType;
				_view.itemLayer.alpha = 0.5;
				_view.itemLayer.mouseChildren = false;
			}
		}
		
		public function set dragItemType( value:int ):void
		{
			if( _editType==EditType.ITEM )
			{
				_dragManager.startDrag( value );
			}
		}
		
		public function set penSize( value:int ):void
		{
			_pathController.penSize = value;
		}
		
		public function set penType( value:Boolean ):void
		{
			_pathController.isRhombus = value;
		}
		
		private var _hasB:Boolean = false;
		private function selectBeginPos():void
		{
			if( _hasE )
			{
				_hasE = false;
				_view.removeEventListener( MouseEvent.MOUSE_DOWN, onSelectEndPos );
			}
			if( !_hasB )
			{
				_hasB = true;
				setTips( "选择起始点" );
				_view.addEventListener( MouseEvent.MOUSE_DOWN, onSelectFirstPos, false, 11, true );
			}
		}
		
		private var _hasE:Boolean = false;
		private function selectEndPos():void
		{
			if( !_hasB && !_hasE )
			{
				_hasE = true;
				setTips( "选择结束点" );
				_view.addEventListener( MouseEvent.MOUSE_DOWN, onSelectEndPos, false, 11, true );
			}
		}
		
		private var _ptFirst:Point;
		private function onSelectFirstPos( e:MouseEvent ):void
		{
			_hasB = false;
			_view.removeEventListener( MouseEvent.MOUSE_DOWN, onSelectFirstPos );
			
			_ptFirst = new Point( e.stageX, e.stageY );
			_ptFirst = _view.globalToLocal( _ptFirst );
			var arr:Array = _gridController.getGridFromXY( _ptFirst.x, _ptFirst.y );
			_ptFirst.x = arr[0];
			_ptFirst.y = arr[1];
			arr = _gridController.getCenterXYFromGrid( arr[0], arr[1] );
			
			_view.searchLayer.graphics.clear();
			_view.searchLayer.graphics.beginFill(0);
			_view.searchLayer.graphics.drawCircle( arr[0], arr[1], 10);
			_view.searchLayer.graphics.endFill();
		}
		
		private function onSelectEndPos( e:MouseEvent ):void
		{
			_hasE = false;
			_view.removeEventListener( MouseEvent.MOUSE_DOWN, onSelectEndPos );
			setTips( "" );
			
			var pt:Point = new Point( e.stageX, e.stageY );
			pt = _view.globalToLocal( pt );
			var arr:Array = _gridController.getGridFromXY( pt.x, pt.y );
			
			var arr1:Array = _gridController.getCenterXYFromGrid( arr[0], arr[1] );
			
			_view.searchLayer.graphics.beginFill(0xff0000);
			_view.searchLayer.graphics.drawCircle( arr1[0], arr1[1], 10);
			_view.searchLayer.graphics.endFill();
			
			var t:uint = getTimer();
			var arrPath:Array = _pathController.getSearchPath2( [_ptFirst.x, _ptFirst.y], arr );
			t = getTimer() - t;
			setTips( t + "ms" );
			if( arrPath != null )
			{
				var len:int = arrPath.length;
				var g:Graphics = _view.searchLayer.graphics;
				g.lineStyle( 1, 0x00ff00 );
				arr = _gridController.getCenterXYFromGrid( arrPath[0], arrPath[1] );
				g.moveTo( arr[0], arr[1] );
				for( var i:int=2; i < len; i += 2 )
				{
					arr = _gridController.getCenterXYFromGrid( arrPath[i], arrPath[i+1] );
					g.lineTo( arr[0], arr[1] );
				}
			}
		}
		
		private function onMouseDown( e:MouseEvent ):void
		{
			if( _isDrag && _isCreated )
			{
				e.stopImmediatePropagation();
				_view.startDrag();
				StageManager.stage.addEventListener( MouseEvent.MOUSE_UP, onMouseUp, false, 0, true );
			}
		}
		
		private function onMouseMove( e:MouseEvent ):void
		{
			var x:int = _view.mouseX;
			var y:int = _view.mouseY;
			var arr:Array = _gridController.getGridFromXY( x, y );
			
			EditBarController.instance.setMouseInfo( x, y, arr[0], arr[1] );
		}
		
		private function onMouseUp( e:MouseEvent ):void
		{
			_view.stopDrag();
			StageManager.stage.removeEventListener( MouseEvent.MOUSE_UP, onMouseUp );
		}
		
		private function onKeyDown( e:KeyboardEvent ):void
		{
			if( !_isCreated ) return;
			
			var keyCode:uint = e.keyCode;
			if( keyCode==Keyboard.SPACE )
			{
				_isDrag = true;
			}
			else if( keyCode==Keyboard.A )
			{
				selectBeginPos();
			}
			else if( keyCode==Keyboard.S )
			{
				selectEndPos();
			}
		}
		
		private function onKeyUp( e:KeyboardEvent ):void
		{
			if( !_isCreated ) return;
			
			if( e.keyCode==Keyboard.SPACE )
			{
				_isDrag = false;
			}
			else if( e.keyCode==Keyboard.ESCAPE )
			{
				dragItemType = SceneItemType.NONE;
			}
		}
		
		private function onClickStage( e:MouseEvent ):void
		{
			if( !(e.target is TextField) )
			{
				StageManager.stage.focus = null;
			}
		}
		
		private var _infoPopupController:MapInfoPopupController;
		private function get infoPopupController():MapInfoPopupController
		{
			if( _infoPopupController==null ) _infoPopupController = new MapInfoPopupController();
			return _infoPopupController;
		}
		
		private function clear():void
		{
			_view.close();
			
			_view.imageBG.source = "";
			_isCreated = false;
			_dragManager.clear();
			_gridController.clear();
			_pathController.clear();
			
			StageManager.stage.removeEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
			StageManager.stage.removeEventListener( KeyboardEvent.KEY_UP, onKeyUp );
		}
	}
}













